

#include "Visualizacion.h"



Visualizacion::Visualizacion()
{


}

void Visualizacion::Incializar()
{
	if(enmTipoSesion == TRANSPORTAR_CUBOS)
	{
		intNroTriangsCubo = objSimulacion.getOneCubo(0).getSupTriang().get_NroTriangs();
		intNroVerticesCubo = objSimulacion.getOneCubo(0).getSupTriang().get_NroVertices();
	}
	else if(enmTipoSesion == ORDENAR_CUBOS)
	{
		intNroTriangsCubo = objSimulacion.getOneCubo(0).getSupTriang().get_NroTriangs();
		intNroVerticesCubo = objSimulacion.getOneCubo(0).getSupTriang().get_NroVertices();

		for(int i=0;i<=intNroCubos;i++)
		{
			Vector4f v1;
			Vector4f v2;
			Vector4f v3;

			vMatAmbCubo.push_back(v1);
			vMatDifCubo.push_back(v2);
			vMatSpcCubo.push_back(v3);
			vMatShnCubo.push_back(0.0);
		}
	}
	else if(enmTipoSesion == SIMULACION_HIGADO)
	{
		intNroTriangsOrg = objSimulacion.getOrgano().getSupTriang().get_NroTriangs();
		intNroVerticesOrg = objSimulacion.getOrgano().getSupTriang().get_NroVertices();
	}
	else
	{
		throw new exception;
	}
}


void Visualizacion::RecalcularNormales()
{
    unsigned int intNroNodosModificados = objSimulacion.getOrgano().getMass_Spring_Model().getNroNodosModificados();
    unsigned int intNroCaras = 0;
    unsigned int intValorTemp = 0;

    for(unsigned int i=0;i<=intNroNodosModificados;i++){
        intValorTemp = objSimulacion.getOrgano().getMass_Spring_Model().getOneNodoModificado(i);

        cout << intValorTemp << endl;

        intNroCaras = objSimulacion.getOrgano().getSupTriang().get_Vertice(intValorTemp)->getNroConexionesCara();

        for(unsigned int j=0;j<=intNroCaras;j++)
        {
            objSimulacion.getOrgano().getSupTriang().get_Triangulo(objSimulacion.getOrgano().getSupTriang().get_Vertice(objSimulacion.getOrgano().getMass_Spring_Model().getOneNodoModificado(i))->getOneConCara(j)).CalcularNormal();
        }

        objSimulacion.getOrgano().getSupTriang().get_Vertice(objSimulacion.getOrgano().getMass_Spring_Model().getOneNodoModificado(i))->CalcularNormal();
    }
}

void Visualizacion::CastShadow(int nro, float *lp)
{
	unsigned int i, j, k, jj;
	unsigned int p1, p2;
	float side;
	double dblX1, dblY1, dblZ1, dblX2, dblY2, dblZ2;

	//set visual parameter
	for(i=0;i<objSimulacion.getOneCubo(nro).getSupTriang().get_NroTriangs();i++)
	{
		// chech to see if light is in front or behind the plane (face plane)
		vector<Triangulo> vTriangulos;

		vTriangulos = objSimulacion.getOneCubo(nro).getSupTriang().get_Triangulos();

		side =	vTriangulos[i].getPlano().getA()*lp[0]+
				vTriangulos[i].getPlano().getB()*lp[1]+
				vTriangulos[i].getPlano().getC()*lp[2]+
				vTriangulos[i].getPlano().getD()*lp[3];
		if(side>0) objSimulacion.getOneCubo(nro).getSupTriang().get_Triangulo(i).setVisible(true);
		else objSimulacion.getOneCubo(nro).getSupTriang().get_Triangulo(i).setVisible(false);
	}
	
	glDisable(GL_LIGHTING);
	glDepthMask(GL_FALSE);
	glDepthFunc(GL_LEQUAL);

	glEnable(GL_STENCIL_TEST);
	glColorMask(0, 0, 0, 0);
	glStencilFunc(GL_ALWAYS, 1, 0xffffffff);

	// first pass, stencil operation decreases stencil value
	glFrontFace(GL_CCW);
	glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
	for (i=0; i< objSimulacion.getOneCubo(nro).getSupTriang().get_NroTriangs();i++){
		if (objSimulacion.getOneCubo(nro).getSupTriang().get_Triangulo(i).getVisible())
			for (j=0;j<3;j++){
				k = objSimulacion.getOneCubo(nro).getSupTriang().get_Triangulo(i).getOneVecino(j);
				if ((!k) || (!objSimulacion.getOneCubo(nro).getSupTriang().get_Triangulo(i).getVisible())){
					// here we have an edge, we must draw a polygon
					p1 = objSimulacion.getOneCubo(nro).getSupTriang().get_Triangulo(i).getOneIndice(j);
					jj = (j+1)%3;
					p2 = objSimulacion.getOneCubo(nro).getSupTriang().get_Triangulo(i).getOneIndice(jj);

					//calculate the length of the vector
					dblX1 = (objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p1)->getX()-lp[0])*100;
					dblY1 = (objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p1)->getY()-lp[1])*100;
					dblZ1 = (objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p1)->getZ()-lp[2])*100;

					dblX2 = (objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p2)->getX()-lp[0])*100;
					dblY2 = (objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p2)->getY()-lp[1])*100;
					dblZ2 = (objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p2)->getX()-lp[2])*100;
					
					//draw the polygon
					glBegin(GL_TRIANGLE_STRIP);
					glVertex3f(objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p1)->getX(),
						objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p1)->getY(),
						objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p1)->getZ());
					glVertex3f(objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p1)->getX()+dblX1,
						objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p1)->getY()+dblY1,
						objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p1)->getZ()+dblZ1);
					glVertex3f(objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p2)->getX(),
						objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p2)->getY(),
						objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p2)->getZ());
					glVertex3f(objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p2)->getX()+dblX2,
						objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p2)->getY()+dblY2,
						objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p2)->getX()+dblZ2);
					glEnd();
				}
			}
	}

	//second pass, stencil operation increases stencil value
	glFrontFace(GL_CW);
	glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
	for (i=0; i< objSimulacion.getOneCubo(nro).getSupTriang().get_NroTriangs();i++){
		if (objSimulacion.getOneCubo(nro).getSupTriang().get_Triangulo(i).getVisible())
			for (j=0;j<3;j++){
				k = objSimulacion.getOneCubo(nro).getSupTriang().get_Triangulo(i).getOneVecino(j);
				if ((!k) || (!objSimulacion.getOneCubo(nro).getSupTriang().get_Triangulo(i).getVisible())){
					// here we have an edge, we must draw a polygon
					p1 = objSimulacion.getOneCubo(nro).getSupTriang().get_Triangulo(i).getOneIndice(j);
					jj = (j+1)%3;
					p2 = objSimulacion.getOneCubo(nro).getSupTriang().get_Triangulo(i).getOneIndice(jj);

					//calculate the length of the vector
					dblX1 = (objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p1)->getX()-lp[0])*100;
					dblY1 = (objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p1)->getY()-lp[1])*100;
					dblZ1 = (objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p1)->getZ()-lp[2])*100;

					dblX2 = (objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p2)->getX()-lp[0])*100;
					dblY2 = (objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p2)->getY()-lp[1])*100;
					dblZ2 = (objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p2)->getX()-lp[2])*100;
					
					//draw the polygon
					glBegin(GL_TRIANGLE_STRIP);
					glVertex3f(objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p1)->getX(),
						objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p1)->getY(),
						objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p1)->getZ());
					glVertex3f(objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p1)->getX()+dblX1,
						objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p1)->getY()+dblY1,
						objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p1)->getZ()+dblZ1);
					glVertex3f(objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p2)->getX(),
						objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p2)->getY(),
						objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p2)->getZ());
					glVertex3f(objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p2)->getX()+dblX2,
						objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p2)->getY()+dblY2,
						objSimulacion.getOneCubo(nro).getSupTriang().get_Vertice(p2)->getX()+dblZ2);
					glEnd();
				}
			}
	}



	glFrontFace(GL_CCW);
	glColorMask(1, 1, 1, 1);

	//draw a shadowing rectangle covering the entire screen
	glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glStencilFunc(GL_NOTEQUAL, 0, 0xffffffff);
	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
	glPushMatrix();
	glLoadIdentity();
	glBegin(GL_TRIANGLE_STRIP);
		glVertex3f(-0.1f, 0.1f,-0.10f);
		glVertex3f(-0.1f,-0.1f,-0.10f);
		glVertex3f( 0.1f, 0.1f,-0.10f);
		glVertex3f( 0.1f,-0.1f,-0.10f);
	glEnd();
	glPopMatrix();
	glDisable(GL_BLEND);

	glDepthFunc(GL_LEQUAL);
	glDepthMask(GL_TRUE);
	glEnable(GL_LIGHTING);
	glDisable(GL_STENCIL_TEST);
	glShadeModel(GL_SMOOTH);
}

